/** 
Copyright (c) 2010, Sheikh Abdul Wahid Ahmed
Details @ http://extremecodeworld.codeplex.com/license
**/

using System;
using System.Collections;
using System.Data;
using System.Xml;
using EXtremecode.Utils;
using EXtremecode.Common; 


namespace EXtremecode.EntityDefinition
{
	/// <summary>
	/// Summary description for DBEntityField.
	/// </summary>
	public class DBEntityField:EntityField
	{
		
		
		private string m_strFieldType;
		private bool m_bKeyField;
		private bool m_bComputed;
		private bool m_bIsAutoGenerated;
		private bool m_bIsUnique;
		private bool m_bIsNullable;
		
		public DBEntityField(DataColumn col,DBEntity entityOwner):this(col,DBEntity.FieldType.NATIVE,entityOwner)
		{
		}
		public DBEntityField(DataColumn col,string strFieldType,DBEntity entityOwner):base(col.ColumnName,GetUDType(col),entityOwner)
		{
			m_bKeyField=IsKeyField(col);
			m_strFieldType=strFieldType;
			m_bComputed=col.AutoIncrement;
			m_bIsAutoGenerated=IsAutoGeneratedfield(col);
			m_bIsUnique=col.Unique;
			m_bIsNullable= col.AllowDBNull;

		}
		
		/// <summary>
		///	 IsKeyField
		/// </summary>
		/// <param name="col"></param>
		/// <returns>if the field is part of the primary key then return true.</returns>
		private bool IsKeyField(DataColumn col)
		{
			foreach(DataColumn c in col.Table.PrimaryKey)
			{
				if(c==col)return true;
			}
			
			return false;
			
		}
		
		
		/// <summary>
		/// IsAutoGeneratedfield
		/// 
		/// if its a key field, type is like integer and not an autoIncreament field
		///	then mark it is autoGenerated field.
		///	its value will be generated by using token table.
		/// </summary>
		/// <param name="col"></param>
		/// <returns></returns>
		private bool IsAutoGeneratedfield(DataColumn col)
		{
			if(col.Unique && col.DataType.Name != "DateTime" && col.DataType.Name != "String"  && col.DataType.Name != "Byte[]")
			{
				foreach(DataColumn c in col.Table.PrimaryKey)
				{
					if(c==col)return true & !col.AutoIncrement;
				}
			}
			return false;
		}


		/// <summary>
		/// GetUDType
		/// 
		/// for each column we have associated respective user defined type
		///	by using property 'ExtendedProperties'.
		/// </summary>
		/// <param name="dc"></param>
		/// <returns></returns>
		private static string GetUDType(DataColumn dc)
		{
			return dc.ExtendedProperties[Constants.UD_TYPE].ToString();
		}
		
		
		
		public override XmlElement BuildXml(XmlDocument ownerDocument)
		{
			XmlElement element= base.BuildXml (ownerDocument);
			XmlAttribute atb;
			
			//----FieldType---
			atb= ownerDocument.CreateAttribute("type");
			atb.InnerText=m_strFieldType;
			element.Attributes.Append(atb);

			//----key---
			atb= ownerDocument.CreateAttribute("key");
			atb.InnerText=m_bKeyField.ToString().ToLower();
			element.Attributes.Append(atb);
			
			//----tokenid---
			if(m_bIsAutoGenerated)
			{
				atb= ownerDocument.CreateAttribute("tokenid");
				atb.InnerText=string.Format("{0}-{1}",m_entityOwner.Name,m_strEntityFieldName);
				element.Attributes.Append(atb);
			}

			//----computed---
			atb= ownerDocument.CreateAttribute("computed");
			atb.InnerText=m_bComputed.ToString().ToLower();
			element.Attributes.Append(atb);

			//----unique---
			atb= ownerDocument.CreateAttribute("unique");
			atb.InnerText=m_bIsUnique.ToString().ToLower();
			element.Attributes.Append(atb);

			//----nullable---
			atb= ownerDocument.CreateAttribute("nullable");
			atb.InnerText=(m_bIsNullable).ToString().ToLower();
			element.Attributes.Append(atb);

			//----autoGenerated---
			atb= ownerDocument.CreateAttribute("autoGenerated");
			atb.InnerText=m_bIsAutoGenerated.ToString().ToLower();
			element.Attributes.Append(atb);

			return element;
		}

	}
}
